package com.ygqh.baby.interceptor;

import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.model.BaseQueryRequest;
import com.ygqh.baby.utils.DateConvertUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.context.request.NativeWebRequest;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.util.*;

public class QueryInfoArgumentResolver extends YgExceptionHandler implements WebArgumentResolver {
    private final Log logger = LogFactory.getLog(getClass());

    @Override
    public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception {
        Set<Class> statusClzs = new HashSet<Class>();
        statusClzs.add(Long.class);
        statusClzs.add(Date.class);

        Class parameterType = methodParameter.getParameterType();
        Type type = methodParameter.getGenericParameterType();
        Class componentType = parameterType;
        if (type instanceof ParameterizedType) {
            componentType = (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0];
        }

        if (methodParameter.getParameterType().isArray()) {
            componentType = methodParameter.getParameterType().getComponentType();
        }

        logger.debug("生成类：" + componentType.getName());

        Class superclass = parameterType.getSuperclass();
        // 分页参数拦截
        if (parameterType.equals(QueryInfo.class) || superclass.equals(BaseQueryRequest.class)) {
            return extractQueryInfo(methodParameter, webRequest);
        }

        String argName = methodParameter.getParameterName();
        String paramName = argName;
        String[] paramValues = webRequest.getParameterValues(paramName);

        List<String> paramValuesList = new ArrayList<String>();
        if (statusClzs.contains(componentType)) {
            if (paramValues != null) {
                for (String value : paramValues) {
                    if (value != null && value.indexOf(",") > 0) {// 低版本编码错误纠正
                        paramValuesList.addAll(Arrays.asList(value.split(",")));
                    } else {
                        paramValuesList.add(value);
                    }
                }
                /*
                 * for(int i=0; i<paramValuesList.size(); i++){
                 * if(paramValuesList.get(i).indexOf("waitting")>=0){
                 * paramValuesList.set(i,
                 * paramValuesList.get(i).replaceAll("waitting", "waiting")); }
                 * }
                 */
            }
            List<Object> finalParamValuesList = new ArrayList<Object>();
            if (componentType.equals(Long.class)) {
                for (String val : paramValuesList) {
                    if (val == null || StringUtils.isEmpty(val.trim())) {

                    } else {
                        try {
                            finalParamValuesList.add(Long.valueOf(val));
                        } catch (Exception e) {
                            logger.error("参数映射失败，method=" + methodParameter.getMethod().getName());
                            e.printStackTrace();
                            throw e;
                        }
                    }

                }
            } else if (componentType.equals(Date.class)) {
                for (String val : paramValuesList) {
                    if (val == null || StringUtils.isEmpty(val.trim())) {

                    } else {
                        try {
                            finalParamValuesList.add(this.dateConverter(val));
                        } catch (Exception e) {
                            logger.error("参数映射失败，method=" + methodParameter.getMethod().getName());
                            e.printStackTrace();
                            throw e;
                        }
                    }

                }

            } else {
                for (String name : paramValuesList) {
                    if (StringUtils.isNotEmpty(name)) {
                        finalParamValuesList.add(Enum.valueOf(componentType, name));
                    }
                }
            }
            if (!finalParamValuesList.isEmpty()) {
                if (methodParameter.getParameterType().isArray()) {
                    Object[] objs = (Object[]) Array.newInstance(componentType, finalParamValuesList.size());
                    for (int i = 0; i < finalParamValuesList.size(); i++) {
                        objs[i] = finalParamValuesList.get(i);
                    }
                    return objs;
                } else {
                    return finalParamValuesList.get(0);
                }
            } else {
                return null;
            }
        }

        return UNRESOLVED;
    }

    private QueryInfo extractQueryInfo(MethodParameter methodParameter, NativeWebRequest webRequest) {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        String start = request.getParameter("start");
        String limit = request.getParameter("limit");
        String page = request.getParameter("page");
        String modifyTime = request.getParameter("modifyTime");
        String iDisplayStart = request.getParameter("iDisplayStart");
        String iDisplayLength = request.getParameter("iDisplayLength");
        String startId = request.getParameter("startId");
        String endId = request.getParameter("endId");

        Integer i_start = null;
        Integer i_limit = null;
        Integer i_page = null;
        if (StringUtils.isNotEmpty(start)) {
            i_start = Integer.parseInt(start);
        }
        if (StringUtils.isNotEmpty(limit)) {
            i_limit = Integer.parseInt(limit);
        }
        if (StringUtils.isNotEmpty(page)) {
            i_page = Integer.parseInt(page);
        }
        if (StringUtils.isNotEmpty(iDisplayStart)) {
            i_start = Integer.parseInt(iDisplayStart);
        }
        if (StringUtils.isNotEmpty(iDisplayLength)) {
            i_limit = Integer.parseInt(iDisplayLength);
        }
        request.setAttribute("start", start);
        request.setAttribute("limit", limit);
        request.setAttribute("end", limit);
        request.setAttribute("page", page);
        request.setAttribute("startId", startId);
        request.setAttribute("endId", endId);
        request.setAttribute("modifyTime", modifyTime);

        int defaultLimit = 20;

        if (i_start == null && i_limit == null && i_page == null)
            return new QueryInfo(0, defaultLimit);

        QueryInfo queryInfo = null;

        if (i_page == null) {
            if (i_limit == null) {
                queryInfo = new QueryInfo(0, defaultLimit);
            }
            if (i_start == null) {
                i_start = 0;
            }
        }
        if (queryInfo == null)
            queryInfo = new QueryInfo(i_start, i_limit, i_page, modifyTime);

        queryInfo.setLimit(i_limit);
        queryInfo.setStartId(startId);
        queryInfo.setEndId(endId);

        // 配置排序信息
        String sortKey = request.getParameter("sortKey");
        queryInfo.setSortKey(sortKey);

        return queryInfo;
    }

    private Date dateConverter(String value) {

        try {
            String[] format = {DateConvertUtils.DATE_TIME_FORMAT, DateConvertUtils.DATE_FORMAT, DateConvertUtils.MONTH_FORMAT};
            return DateUtils.parseDate(value, format);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;

    }
}
